﻿///-----------------------------------------------------------------------
/// <copyright file="RecordDetailViewModel.cs" company="FactSet Research Systems, Inc.">
///     Copyright © FactSet Research Systems, Inc.  All rights reserved 2012.
/// </copyright>
/// <author>Jonathan K. Barez</author>
///-----------------------------------------------------------------------

namespace HousholdISv2.ViewModel.Core
{
    using System.Windows;
    using System;
    using System.Linq;
    using MVVMCore.ViewModel;
    using MVVMCore.ViewModel.Interface;
    using System.Collections.Generic;
    using MVVMCore.Messaging;
    using MVVMCore.ViewModel.Details;
    using MVVMCore.Interface;
    using System.Windows.Media;

    public class RecordDetailViewModel : FormCollectionViewModel
    {
        #region Fields

        private readonly Dictionary<int, string> errors;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="RecordDetailViewModel"/> class.
        /// </summary>
        public RecordDetailViewModel(params ViewModelBase[] items)
            : base(items)
        {
            this.ErrorMessage =
                new TextViewModel
                    {
                        Foreground = Brushes.Red,
                        FontWeight = FontWeights.Bold,
                    };
            this.errors = new Dictionary<int, string>();
            VerticalSpacing = 5;
            Messenger.Register<ValidationMessage>(this, this.ProcessMessage);
        }

        #endregion Constructors

        #region Events

        #endregion Events

        #region Properties

        public Func<bool> IsValidChecker { get; set; }

        public bool IsValid
        {
            get { return this.IsValidChecker == null || this.IsValidChecker(); }
        }

        public string Errors
        {
            get
            {
                return string.Join(
                    Environment.NewLine,
                    errors.Values
                        .Where(
                            value =>
                            !string.IsNullOrWhiteSpace(value)));
            }
        }

        public TextViewModel ErrorMessage
        {
            get { return GetValue(() => this.ErrorMessage); }
            set
            {
                var last = GetValue(() => this.ErrorMessage);
                SetValue(() => ErrorMessage, value);
                if (last != null)
                {
                    Items.Remove(last);
                }

                if (value != null)
                {
                    Items.Insert(0, value);
                }
            }
        }

        public Func<ICaptionedViewModel, string> Validator { get; set; }

        public bool CanUpdate
        {
            get { return Items.OfType<IValidatedControl>().Any(item => item.IsInputValid); }
        }

        #endregion Properties

        #region Methods

        public T FindCaptionedModel<T>(string caption) where T : class, ICaptionedViewModel
        {
            return this.FindControls<T>(caption).FirstOrDefault();
        }

        public ICaptionedViewModel FindCaptionedModel(string caption)
        {
            return this.FindControls<ICaptionedViewModel>(caption).FirstOrDefault();
        }

        protected override void OnDispose()
        {
            Messenger.Unregister<ValidationMessage>(this, this.ProcessMessage);
            this.Validator = null;
            base.OnDispose();
        }

        protected virtual void ProcessMessage(ValidationMessage message)
        {
            if (!this.Contains(message.Sender) || this.Validator == null)
            {
                return;
            }

            message.Result = this.Validator(message.Sender as ICaptionedViewModel);
            this.RegisterValidationMessage(message.Sender.GetHashCode(), message.Result);
        }

        protected virtual void RegisterValidationMessage(int controlCode, string errorMessage)
        {
            if (string.IsNullOrWhiteSpace(errorMessage))
            {
                if (errors.ContainsKey(controlCode))
                {
                    errors.Remove(controlCode);
                }
            }
            else
            {
                errors[controlCode] = errorMessage;
            }

            this.RefreshErrorMessage();
        }

        private void RefreshErrorMessage()
        {
            this.ErrorMessage.Text = this.Errors;
        }

        private IEnumerable<T> FindControls<T>(string caption) where T : ICaptionedViewModel
        {
            return
                this.Items.OfType<T>().Where(
                    item =>
                    !string.IsNullOrEmpty(item.Caption) &&
                    (string.Equals(item.Caption, caption, StringComparison.OrdinalIgnoreCase) ||
                     item.Caption.IndexOf(caption, StringComparison.OrdinalIgnoreCase) == 0 ||
                     item.Caption.IndexOf(caption, StringComparison.OrdinalIgnoreCase) > 0));
        }

        #endregion Methods
    }
}